using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace Camalon.Drawing.Design
{
	/// <summary>
	/// Summary description for Ruler.
	/// </summary>
	internal class Ruler : System.Windows.Forms.Control
	{
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.Container components = null;

		RulingPanel		_rulingPanel	= null;
		Pen				_borderPen		= new Pen(Color.FromArgb(196,Color.Silver), 1.0f);
		SolidBrush		_backgBrush		= new SolidBrush( Color.FromArgb(96,Color.Silver));
		SolidBrush		_textBrush		= new SolidBrush(Color.Black);//Color.FromArgb(96,Color.Black));
		StringFormat	_textFormat		= StringFormat.GenericDefault.Clone() as StringFormat;
		bool			_horizontal		= true;
		Point			_range			= Point.Empty;// From x( left ) to y (right) in x direction if horizontal, else in y direction

		
		public Ruler()
		{
			SetStyle(System.Windows.Forms.ControlStyles.DoubleBuffer, true);
			SetStyle(System.Windows.Forms.ControlStyles.AllPaintingInWmPaint, true);
			SetStyle(System.Windows.Forms.ControlStyles.ResizeRedraw, true);
			SetStyle(System.Windows.Forms.ControlStyles.UserPaint, true);
			SetStyle(System.Windows.Forms.ControlStyles.SupportsTransparentBackColor,true);

			InitializeComponent();

			this.Font		= new Font("Microsoft Sans Serif",8.25f);//,FontStyle.Bold);
			_textFormat.LineAlignment	= _textFormat.Alignment = StringAlignment.Center;
			_textFormat.Trimming		= StringTrimming.EllipsisPath;
			_textFormat.FormatFlags		= StringFormatFlags.NoWrap;



		}




		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if( components != null )
					components.Dispose();
			}
			base.Dispose( disposing );
		}


		#region Component Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify 
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{

		}
		#endregion


		protected internal Color BorderColor
		{
			set
			{
				_borderPen.Color = value;
			}
		}


		protected new internal Color BackColor
		{
			set
			{
				_backgBrush.Color = value;
			}
		}


		protected internal RulingPanel RulingPanel
		{
			set
			{ 
				_rulingPanel = value;
				_horizontal  = _rulingPanel.HRuler.Equals( this );

				Invalidate(false);
			}
		}

		protected internal Point Range
		{
			get{ return _range;}
			set
			{
				if( value == _range ) return;

				_range = value;
				this.Invalidate( );
			}
			
		}
		
		private Rectangle GetRangeBounds()
		{
			int margin= 2;
			Point		scrollPosition	= _rulingPanel.AutoScrollPosition;

			if( _horizontal) 
				return new Rectangle( _range.X + 2 + scrollPosition.X, margin, _range.Y- _range.X -1, this.Height - (2*margin)-1 );
			else 
				return new Rectangle(margin, _range.X  + 1+ scrollPosition.Y, this.Width - ( 2*margin) - 1, _range.Y - _range.X ) ;
		}
		

		protected override void OnPaint(PaintEventArgs e)
		{
			if( _rulingPanel == null)
			{
				base.OnPaint(e);
				return;
			}

			PaintRuler(e.Graphics);

		}


		private void PaintRuler( Graphics g )
		{
			if( _rulingPanel == null) return;

			GraphicsContainer container = g.BeginContainer();

			try
			{

				g.CompositingQuality = CompositingQuality.HighSpeed;
				g.PixelOffsetMode= PixelOffsetMode.HighSpeed;


				Rectangle rect = this.ClientRectangle;
				rect.Height--;
				rect.Width--;

				if( _backgBrush != null) g.FillRectangle( _backgBrush, rect);
				
				Point		scrollPosition	= _rulingPanel.AutoScrollPosition;
				Size		scrollMinSize	= _rulingPanel.AutoScrollMinSize;
				Size		gridSize		= _rulingPanel.GridSize;
				int			gridPageSize	= _rulingPanel.GridPageSize;

				if( _horizontal )
				{
					int scrollSizeX		= scrollMinSize.Width < _rulingPanel.Width  ? _rulingPanel.Width  : scrollMinSize.Width;

					int mulVal = gridSize.Width * gridPageSize; // Fitting text area
					if( mulVal < 30 ) mulVal = mulVal * ((30 / mulVal) + 1); 
					else if( mulVal >= 60 && gridSize.Width <= 30)
					{
						if( (gridPageSize%7) == 0 && ((mulVal / 7)>=30)) mulVal = mulVal/7;
						else
						if( (gridPageSize%5) == 0 && ((mulVal / 5)>=30)) mulVal = mulVal/5;
						else
						if( (gridPageSize%3) == 0 && ((mulVal / 3)>=30)) mulVal = mulVal/3;
						else
						if( (gridPageSize%2) == 0 && ((mulVal / 2)>=30)) mulVal = mulVal/2;
					}

				

					Rectangle textRect = new Rectangle(0,0, mulVal , this.Height);

					
					int iStart= mulVal;
					int count = 1;
					if( this.RightToLeft == RightToLeft.Yes && _rulingPanel.VScrollVisible )
					{
						g.TranslateTransform(SystemInformation.VerticalScrollBarWidth,0 );
						iStart = 0;
						count = 0;
					}
				
					// Draw Range
					//------------------------
					Rectangle rangeRect = GetRangeBounds();
					if( rangeRect.Size != Size.Empty)	g.FillRectangle( Brushes.White, rangeRect); 

					//-------------------------------------------------------------------------------------
					//Paint V-Grid
					//-------------------------------------------------------------------------------------
					RectangleF clipBounds = new RectangleF( 0,0, this.Width, this.Height);
					clipBounds.Inflate( 0, -5f);
					g.SetClip( clipBounds, CombineMode.Exclude);
					g.TranslateTransform( 1,0);
					_rulingPanel.PaintGrid( g, Camalon.Drawing.Design.RulingPanel.PaintGridArg.Vertical, this.Size);
					g.TranslateTransform( -1,0);
					g.ResetClip();
					//-------------------------------------------------------------------------------------

					for( int i = iStart ; i <= scrollSizeX ; i += mulVal )
					{
						textRect.X = (i + scrollPosition.X ) - ( mulVal / 2 );
						int numVal = mulVal * count++;
						g.DrawString(numVal.ToString(), this.Font,  _textBrush,textRect,_textFormat);
					}


				}
				else
				{


					int scrollSizeY = scrollMinSize.Height < _rulingPanel.Height  ? _rulingPanel.Height  : scrollMinSize.Height;

					int mulVal = gridSize.Height * gridPageSize; // Fitting text area
					if( mulVal < 30 ) mulVal = mulVal * ((30 / mulVal) + 1); 
					else if( mulVal >= 60 && gridSize.Height <= 30)
					{
						if( (gridPageSize%7) == 0 && ((mulVal / 7)>=30)) mulVal = mulVal/7;
						else
							if( (gridPageSize%5) == 0 && ((mulVal / 5)>=30)) mulVal = mulVal/5;
						else
							if( (gridPageSize%3) == 0 && ((mulVal / 3)>=30)) mulVal = mulVal/3;
						else
							if( (gridPageSize%2) == 0 && ((mulVal / 2)>=30)) mulVal = mulVal/2;
					}


					// Draw Range
					//------------------------
					Rectangle rangeRect = GetRangeBounds();
					if( rangeRect.Size != Size.Empty)	
					{
						//Little correcture
						rangeRect.Y++;
						rangeRect.Height--;
						//------------------
						g.FillRectangle( Brushes.White, rangeRect);
					}
					//-------------------------------------------------------------------------------------
					//Paint H-Grid
					//-------------------------------------------------------------------------------------
					RectangleF clipBounds = new RectangleF( 0,0, this.Width, this.Height);
					clipBounds.Inflate( -5f, 0);
					g.SetClip( clipBounds, CombineMode.Exclude);
					g.TranslateTransform( 0,1);
					_rulingPanel.PaintGrid( g, Camalon.Drawing.Design.RulingPanel.PaintGridArg.Horizontal, this.Size);
					g.TranslateTransform( 0,-1);
					g.ResetClip();
					//-------------------------------------------------------------------------------------
					
					g.TranslateTransform(0,scrollPosition.Y + scrollSizeY );
					g.RotateTransform(-90);

					Rectangle textRect =new Rectangle( 0 ,	0, mulVal, this.Width);

					int count = 1;
					for( int i = scrollSizeY - mulVal ; i >=0 ; i -= mulVal)
					{
						textRect.X = i - (mulVal / 2) - 2;
						int numVal = mulVal * count++;
						//Convert.ToString(numVal,null)
						g.DrawString( numVal.ToString(), this.Font,  _textBrush,textRect,_textFormat);
					}

				}

				g.ResetTransform();

				if( _borderPen != null ) g.DrawRectangle( _borderPen,rect);

			}
			catch( Exception exc)
			{
				FileWatcher.WriteLine("Ruler OnPaint failed" + exc.Message);
			}
			finally
			{
				g.EndContainer(container);
			}

		}


	}
}
